package com.openvid.webrtc.openvid.http;

import android.util.ArrayMap;
import android.util.Base64;
import android.util.Log;

import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * @author jinyf
 */
public class RtcRoomerClient {


    private static final String TAG = "HTTP";

//    public static RtcRoomerClient mInstance = new RtcRoomerClient();
//
//    public static RtcRoomerClient getInstance() {
//        return mInstance;
//    }
//
//    private RtcRoomerClient() {
//    }

    private HttpClient mRtcHttpClient;
    private Headers mHeaders;


    private void initHeaders(String uname, String pwd) {
        String b64 = Base64.encodeToString((uname + ":" + pwd).getBytes(), Base64.DEFAULT);
        Map<String, String> mp = new ArrayMap<>();
        mp.put("Content-Type", "application/json; charset=utf-8");
        mp.put("Authorization","Basic "+b64);
        mHeaders = Headers.of(mp);
    }

    private void requestSession(String roomSessionId, ResultCallback<String> callback) {
        JSONObject params = new JSONObject();
        try {
            params.put("customSessionId", roomSessionId);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        RequestBody sessionBody = getBody(params);
        postRequest("/api/sessions", sessionBody, new ResultCallback<String>() {
            @Override
            public void onSuccess(String result) {
                requestRoomToken(roomSessionId, callback);
            }

            @Override
            public void onFail(int code, String msg) {
                if (code == 409) {
                    onSuccess("");
                }
            }
        });
    }


    private void requestRoomToken(String roomSessionId, ResultCallback<String> callback) {
        postRequest("/api/sessions/" + roomSessionId + "/connection", getBody(new JSONObject()), new ResultCallback<String>() {
            @Override
            public void onSuccess(String result) {
                try {
                    JSONObject jsonObject = new JSONObject(result);
                    if (jsonObject.has("token")) {
                        String token = jsonObject.optString("token");
                        callback.onSuccess(token);
                        return;
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                callback.onFail(-7777, "no token");
            }

            @Override
            public void onFail(int code, String msg) {
                callback.onFail(code, msg);
            }
        });
    }

    private RequestBody getBody(JSONObject jsonObject) {
        return RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonObject.toString());
    }

    private void postRequest(String path, RequestBody body, ResultCallback<String> callback) {
        try {
            mRtcHttpClient.httpCall(path, "POST", "application/json", mHeaders, body, new okhttp3.Callback() {
                @Override
                public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                    String rs = response.toString();
                    Log.i(TAG, "responseString：" + rs);
                    if (response.isSuccessful()) {
                        String content = response.body().string();
                        callback.onSuccess(content);
                    } else {
                        callback.onFail(response.code(), rs);
                    }
                }

                @Override
                public void onFailure(@NotNull Call call, @NotNull IOException e) {
                    Log.e(TAG, "Error POST " + path, e);
                    callback.onFail(-9999, Log.getStackTraceString(e));
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
            callback.onFail(-8888, Log.getStackTraceString(e));
        }
    }

    public interface ResultCallback<T> {
        void onSuccess(T result);

        void onFail(int code, String msg);
    }

//    public void init(String url, String uname, String pwd) {
//        url = "https://test-live-xy.deepblueai.com/openvidu/";
//        uname = "OPENVIDUAPP";
//        pwd = "password";
//        initHeaders(uname, pwd);
//        mRtcHttpClient = new HttpClient(url);
//    }

    public RtcRoomerClient (String url, String uname, String pwd) {
        initHeaders(uname, pwd);
        mRtcHttpClient = new HttpClient(url);
    }

    public void getRoomToken(String roomSessionId, ResultCallback<String> callback) {
        requestSession(roomSessionId, callback);
    }

}
